package gcu.shiro;

import gcu.module.rbac.daomain.Role;
import gcu.module.rbac.daomain.User;
import gcu.module.rbac.service.RoleService;
import gcu.module.rbac.service.UserService;
import gcu.util.SFormt;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * Created by haol on 2016/9/19.
 * shiro用户授权和认证
 */
public class PermissionRealm extends AuthorizingRealm {

      private Logger logger = LoggerFactory.getLogger(PermissionRealm.class);

      @Autowired
      private UserService userService;
      @Autowired
      private RoleService roleService;


      @Override
      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            String username = (String) principalCollection.getPrimaryPrincipal();
            logger.info("用户[{}]进入授权验证", username);
            User user = userService.queryUserByName(username);
            List<Role> roles = roleService.queryRoleByUser(user.getId());
            List<String> roleSn = new ArrayList<String>();
            for (Role sn : roles) {
                  roleSn.add(sn.getRoleSn());
            }
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            info.setRoles(new HashSet<String>(roleSn));
            logger.info("用户[{}]授权验证完成", username);
            return info;
      }

      @Override
      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
              throws AuthenticationException {
            String username = authenticationToken.getPrincipal().toString();
            String password = new String((char[]) authenticationToken.getCredentials());
            String md5Pwd = ShiroKit.md5Pwd(password, username);
            logger.info("用户[{}]进入登录验证", username);
            User user = userService.queryUserByName(username);

            if (user == null) {
                  throw new UnknownAccountException("用户名不存在");
            } else {
                  if (!user.getPassword().equals(md5Pwd)) {
                        throw new IncorrectCredentialsException("密码错误");
                  }
                  if (user.getStatus().equals("0")) {
                        throw new LockedAccountException("用户账号已被锁定");
                  }
                  List<Role> roles = roleService.queryRoleByUser(user.getId());
                  for (Role role : roles) {
                        if (role.getRoleSn().equals("NO")) {
                              throw new AuthenticationException("当前用户没有分配角色，请分配角色后再登录");
                        }
                  }
            }
            /*更新登录时间*/

            userService.updatTime(SFormt.NOWDATE_y_M_dhms(), username);

          /*  *//*将登陆用户的信息存进session*//*
            SecurityContextHolder.setUser(user);*/

            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password, this.getName());
            /**
             * 很大的疑惑这个
             *   info.setCredentialsSalt(ByteSource.Util.bytes(password));
             *   应该是设置username这个盐值得可是设置就会出错
             *   设置成password就没问题
             */
            info.setCredentialsSalt(ByteSource.Util.bytes(password));
            logger.info("用户[{}]进入登录验证成功", username);
            return info;
      }
}
